fix(seo): immediate EEAT and crawl-surface fixes#393
Conversation
- Fix broken github.com/detached-node sameAs URL -> github.com/julianken (HTTP 404 -> 200) - Replace hardcoded detached-node.com in OG image footers with runtime SITE_DOMAIN - Lift overviewLead out of DisclosureSection so AI crawlers index it unconditionally - Remove priority field from sitemap (Google has ignored it since 2017) - Add CONTACT_EMAIL to site-config (for RSS upgrade in Category E) - Surface visible dateModified on pattern pages (freshness signal) Closes #387
julianken-bot
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Six independent SEO fixes, all narrowly scoped, all consistent with their stated rationale. Diff is 23 additions across 7 files; well below the length threshold for an attention dropoff and easy to audit.
Verification ledger
| Check | Command | Result |
|---|---|---|
| HEAD pinned | gh pr view 393 --json headRefOid |
52ab7396726310baaac04d0e4a59b6497ce101f2 |
pnpm typecheck |
tsc --noEmit |
clean — exit 0, no errors |
pnpm test:unit |
vitest run |
31 files / 525 tests passed |
pnpm lint:adp |
typecheck-sketches + validate-references + check-affiliate-links + lint-changelog | all OK |
pnpm lint (eslint) |
1435 errors / 66638 warnings — none in PR-touched files | pre-existing baseline (R7) |
github.com/julianken HTTP status |
curl -sI |
200 (was 404 for detached-node) — the schema sameAs fix is genuine |
Next.js MetadataRoute.Sitemap.priority optionality |
context7 /vercel/next.js/v16.1.6 docs |
confirmed optional; removal is type-safe |
Hardcoded detached-node.com left at HEAD |
git grep |
0 matches (the one in blog-posting.ts is .dev in a comment) |
Findings
- SUGGESTION —
src/app/(frontend)/agentic-design-patterns/opengraph-image.tsx:25-27/[slug]/opengraph-image.tsx:27-29: duplicateSITE_DOMAINfallback constant across two files. See inline comment.
Bottom line
- Sitemap
priorityremoval: type-safe per Next 16 docs. sameAsURL: I verifiedhttps://github.com/juliankenreturns 200 andhttps://github.com/detached-nodereturns 404. The fix is real.overviewLeadlift: removes the collapsed-by-default rendering ambiguity for non-Google AI crawlers; the<DisclosureSection>was alreadydefaultOpenso visible content is unchanged for human readers; the label "Overview · 1-paragraph mechanism" is now absent which is a deliberate trade.<time dateTime>element:pattern.dateModifiedis typedstring(ISO) intypes.ts:143, so thedateTimeattribute receives a valid value.CONTACT_EMAIL: currently unused; the PR body frames it as forward groundwork for upcoming PRs. Acceptable.
Same-tier note
I am running as opus. If the implementer ran on opus as well, this review has same-tier perplexity-familiarity exposure (arxiv 2410.21819). I did a mandatory R8 second pass with the "this contains at least one improvement" prior; the duplicate-constant SUGGESTION is what surfaced, and I am holding it at SUGGESTION rather than escalating.
|
|
||
| const SITE_DOMAIN = process.env.NEXT_PUBLIC_SERVER_URL | ||
| ? new URL(process.env.NEXT_PUBLIC_SERVER_URL).hostname | ||
| : "detached-node.dev"; |
There was a problem hiding this comment.
Both [slug]/opengraph-image.tsx and opengraph-image.tsx now carry an identical SITE_DOMAIN block with the same "detached-node.dev" literal. If the canonical domain ever changes — or a future env-handling refactor lands — both files need to be edited in lockstep, and there is no compile-time link between them.
Low-cost polish: lift the fallback into src/lib/site-config.ts (alongside siteName, siteAuthor, the new CONTACT_EMAIL, etc.) and import it. That avoids the assertRequiredEnv indirection that the file-header comments deliberately avoid — a plain string export does not transitively touch process.env in the bundle graph, so the Satori/edge concern those comments cite stays addressed.
Non-blocking — the duplication is two lines, the convergence cost is small, and you may prefer the file-local readability. Flagging because the rest of this PR is consolidating site-identity constants and this is the same theme.
|
@Mergifyio queue |
Merge Queue Status
This pull request spent 23 seconds in the queue, including 2 seconds running CI. Required conditions to merge
|
* chore(docs): drop seo-strategy folder; align README to renamed post slug Removes docs/seo-strategy/ — research artifacts from the SEO + AI- discovery analysis funnel, no longer load-bearing now that the gate-1/2/3 work has shipped (#393 #394 #395 #396 #397 #400 #402 #404 #406 #408). History preserved in git. README: align "Recent essays" entry with the renamed post slug (where-agentic-patterns-actually-live → agentic-patterns-in-your-coding-workflow). The rename satisfies Bing Site Scan's 70-char title cap. No redirect deployed — article is two days old, no significant external link equity to preserve. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: defer README slug update; gitignore docs/seo-strategy Address julianken-bot review of PR #409: BLOCKER (README:75) — New slug URL serves an SSR 404 fallback because the Payload post slug hasn't been renamed yet (intentionally deferred until the in-flight Bing Site Scan completes). Reverting the README link change here; it will land in a follow-up PR after the actual Payload slug rename, so the link is never broken in main. Plus: add /docs/seo-strategy/ to .gitignore so future analysis-funnel artifacts (phase-*, context-packets, STATUS.md, issues/) stay on disk without polluting the index. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Six small independent fixes that stop active EEAT damage and remove crawl-surface bugs. Identity-neutral (no Tier C dependencies).
Changes
sameAsURL —src/lib/schema/config.ts:44:github.com/detached-node(HTTP 404) ->github.com/julianken(HTTP 200). A broken external link in schema is worse than no link — it signals an unverifiable entity to Google's entity graph and LLM citation pipelines.detached-node.comin two OG image footers (opengraph-image.tsxline 109 and[slug]/opengraph-image.tsxline 131). Now derives fromprocess.env.NEXT_PUBLIC_SERVER_URLwith.devfallback.overviewLeadout of<DisclosureSection>in pattern pages. The first paragraph of pattern body content was inside an expanded<details>element;<details>is in the DOM and Googlebot indexes it, but non-Google AI crawlers (GPTBot, ClaudeBot, PerplexityBot) have inconsistent rendering of collapsed content. Plain<p>eliminates the ambiguity.priorityfrom sitemap (Google ignores since 2017 per John Mueller, Search Central). KeepslastModifiedandchangeFrequency.CONTACT_EMAILtosrc/lib/site-config.ts— used by Category E's RSS feed upgrade and future schema work.dateModifiedon pattern pages — already in JSON-LD, now rendered as<time>for human freshness signal.Test plan
pnpm lint(includinglint:adp)pnpm test:unitpnpm typecheckpnpm devof a representative pattern page (confirmed overviewLead renders as plain<p>outside details)Coordination
sameAsfix in this PR is a strict subset of issue feat(seo): migrate to Tier C identity (real name + bylines + ProfilePage schema) #388 (Tier C migration), which replaces the entireAUTHOR_CONFIG. If both merge, feat(seo): migrate to Tier C identity (real name + bylines + ProfilePage schema) #388 wins via three-way merge of the array (1-item -> 2-item). If feat(seo): migrate to Tier C identity (real name + bylines + ProfilePage schema) #388 merges first, this PR'ssameAschange becomes a no-op on rebase.Closes #387